#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Lee
# @File    : dhy_connect_row_matplotlib_view.py
# @Time    : 2024/1/15 11:30
import matplotlib
import numpy as np
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QWidget
from util.utm_transformer import transformer_to_utm

matplotlib.use("Qt5Agg")  # 声明使用pyqt5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg  # pyqt5的画布
from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure


class ConnectRowMplWidget(QWidget):
    def __init__(self, parent=None):
        """
        :param parent:
        """
        QWidget.__init__(self, parent)
        self.qCanvas = ConnectRowMatplotlibFigure(parent)
        self.mpl_toolbar = NavigationToolbar(self.qCanvas, self)  # 创建工具条
        # 创建布局，把画布类组件对象和工具条对象添加到QWidget控件中
        self.vbl = QtWidgets.QVBoxLayout()
        self.vbl.addWidget(self.mpl_toolbar)
        self.vbl.addWidget(self.qCanvas)
        self.setLayout(self.vbl)


class ConnectRowMatplotlibFigure(FigureCanvasQTAgg):
    """
        创建一个画布类，并把画布放到FigureCanvasQTAgg
        图中展示内容包括轨迹点、ab基准线，左侧截断线、右侧阶段线
    """

    def __init__(self, parent=None, width=5, height=4, dpi=80):
        """
        :param parent:
        :param width:
        :param height:
        :param dpi:
        """
        figure = Figure(figsize=(width, height), dpi=dpi)
        super(ConnectRowMatplotlibFigure, self).__init__(figure)  # 在父类中激活self.fig
        self.setParent(parent)
        self.ax = figure.add_subplot()
        self.ax.patch.set_alpha(0.5)  # 设置ax区域背景颜色透明度
        FigureCanvasQTAgg.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        # 用于告知包含该widget的layout：该widget的size hint已发生变化，layout会自动进行调整。
        FigureCanvasQTAgg.updateGeometry(self)

        # AB基准线
        self.ab_line, = self.ax.plot([], [], 'r*', linestyle='-.')

        # 左侧截断线
        self.left_line, = self.ax.plot([], [], 'r*', linestyle='--')
        # 右侧截断线
        self.right_line, = self.ax.plot([], [], 'r*', linestyle='--')

        # 动态轨迹点
        self.draw_point, = self.ax.plot([], [], 'bo', picker=5, markersize=3)  # 使用散点图
        self.ax.grid()

        self.parent_obj = parent
        # # 添加matplotlib监听事件
        figure.canvas.mpl_connect('pick_event', self.on_pick_point)

    # 在散点图上选取A、B点
    def on_pick_point(self, event):
        # 获取点的坐标及索引，取到多个点，默认取最后一个
        if type(self.parent_obj).__name__ == "DHYCutTrajectoryView":
            self.parent_obj.get_clicked_index(event.ind.tolist())
        else:
            self.parent_obj.get_clicked_index(event.ind[-1])

    # 更新图表
    def refresh(self):
        self.ax.relim()
        self.ax.autoscale()  # fix bug, 缩放或移动后重新绘制新曲线时视图区域不改
        # https://github.com/ifarup/ciefunctions/issues/124
        # https://github.com/ifarup/ciefunctions/commit/01526210c35ad81e78db9b03169708553c7c660e
        # self.toolbar.update()
        self.draw()
        self.flush_events()

    # 更新散点图
    def update_data(self, point_list):
        # 清空数据后再进行绘制
        if hasattr(self.ax, 'patches'):
            self.ax.patches.clear()
        # self.ax.patches = []
        self.clear_matplotlib_data()
        point_list = np.array(point_list)
        x = point_list[:, 0]
        y = point_list[:, 1]
        self.draw_point.set_xdata(x)
        self.draw_point.set_ydata(y)
        self.refresh()

    # 更新直线坐标
    def update_line(self, points, line_type="0"):
        # # 清空数据后再进行绘制
        # self.clear_matplotlib_data()
        if line_type == "ab_line":
            self.ab_line.set_xdata(points[0])
            self.ab_line.set_ydata(points[1])
        elif line_type == "left_line":
            self.left_line.set_xdata(points[0])
            self.left_line.set_ydata(points[1])
        elif line_type == "right_line":
            self.right_line.set_xdata(points[0])
            self.right_line.set_ydata(points[1])
        else:
            pass

        if self.right_line.get_xdata() and self.left_line.get_xdata():
            _left_x_values = self.left_line.get_xdata()
            _left_y_values = self.left_line.get_ydata()
            _right_x_values = self.right_line.get_xdata()
            _right_y_values = self.right_line.get_ydata()
            if hasattr(self.ax, 'patches'):
                self.ax.patches.clear()
            self.ax.fill([*_left_x_values, _right_x_values[1], _right_x_values[0]],
                         [*_left_y_values, _right_y_values[1], _right_y_values[0]], color='gray', alpha=0.3)
        self.refresh()

    # 清空 matplotlib 数据
    def clear_matplotlib_data(self):
        # 清空A、B线
        self.ab_line.set_xdata([])
        self.ab_line.set_ydata([])

        # 清空左侧截断线
        self.left_line.set_xdata([])
        self.left_line.set_ydata([])

        # 清空右侧阶段线
        self.right_line.set_xdata([])
        self.right_line.set_ydata([])

    def load_data_with_csv_file_path(self, csv_file_path, is_anti_interference_endurance=False):
        _matplotlib_view_points = list()
        if csv_file_path:
            _data = np.loadtxt(csv_file_path, delimiter=',')
            if _data.shape[-1] > 3:
                _matplotlib_view_points = np.delete(_data, [0], axis=1).tolist()  # 删除第一列
            else:
                _matplotlib_view_points = _data[:, [1, 2]].tolist()

            # 抗扰续航时间测试，经纬度转大地坐标系
            if is_anti_interference_endurance:
                if _data.shape[-1] > 3:
                    _matplotlib_view_points = _data[:, [5, 6]].tolist()
                _utm_list = list()
                for point in _matplotlib_view_points:
                    if 0 in point:
                        continue
                    _utm_list.append(list(transformer_to_utm(*point)))
                _matplotlib_view_points = _utm_list

            self.update_data(_matplotlib_view_points)
        return _matplotlib_view_points
